﻿// -------------------------------------------------------------------------
//    @FileName         :    NFCityMapGrid.cpp
//    @Author           :    Gao.Yi
//    @Date             :    2025-09-17
//    @Email			:    445267987@qq.com
//    @Module           :    NFCityMapGrid
//    @Desc             :
//
// -------------------------------------------------------------------------

#include "NFCityMapGrid.h"

NFCityMapGrid::NFCityMapGrid()
{
    if (EN_OBJ_MODE_INIT == NFShmMgr::Instance()->GetCreateMode())
    {
        CreateInit();
    }
    else
    {
        ResumeInit();
    }
}

NFCityMapGrid::~NFCityMapGrid()
{
}

int NFCityMapGrid::CreateInit()
{
    m_nGridIndexInMap = INVALID_ID;
    return 0;
}

int NFCityMapGrid::ResumeInit()
{
    return 0;
}

int NFCityMapGrid::Init(int iGridIndexInMap)
{
    m_nGridIndexInMap = iGridIndexInMap;
    return 0;
}

int NFCityMapGrid::Fin()
{
    NFCityWorldObject* pWorldObject = m_oNpcList.GetHeadNodeObj();
    NFCityWorldObject* pNextWorldObject = nullptr;
    while (pWorldObject)
    {
        pNextWorldObject = m_oNpcList.GetNextNodeObj(pWorldObject);

        pWorldObject->OnLeaveGrid();
        pWorldObject->OnLeaveMap();

        m_oNpcList.RemoveNode(pWorldObject);

        NFCityWorldObject::DestroyObj(pWorldObject);

        pWorldObject = pNextWorldObject;
    }

    pWorldObject = m_oPlayerList.GetHeadNodeObj();
    while (pWorldObject)
    {
        pNextWorldObject = m_oPlayerList.GetNextNodeObj(pWorldObject);

        pWorldObject->OnLeaveGrid();
        pWorldObject->OnLeaveMap();

        m_oPlayerList.RemoveNode(pWorldObject);

        NFCityWorldObject::DestroyObj(pWorldObject);

        pWorldObject = pNextWorldObject;
    }
    return 0;
}

int NFCityMapGrid::EnterGrid(NFCityWorldObject* pWorldObj, const Proto_Vector3& oPos, int iDirection)
{
    CHECK_NULL(0, pWorldObj);

    if (pWorldObj->GetMapGridIdx() != INVALID_ID)
    {
        LOG_ERR(pWorldObj->GetGlobalId(), -1, "WorldObj[{}] not leave Grid!", pWorldObj->GetGlobalId());
        return -1;
    }

    if (pWorldObj->IsNpc())
    {
        m_oNpcList.AddNode(pWorldObj);
    }
    else
    {
        m_oPlayerList.AddNode(pWorldObj);
    }

    pWorldObj->OnEnterGrid(m_nGridIndexInMap, GetGlobalId(), oPos, iDirection);

    return 0;
}

int NFCityMapGrid::LeaveGrid(NFCityWorldObject* pWorldObj)
{
    CHECK_NULL(0, pWorldObj);

    pWorldObj->OnLeaveGrid();

    if (pWorldObj->IsNpc())
    {
        m_oNpcList.RemoveNode(pWorldObj);
    }
    else
    {
        m_oPlayerList.RemoveNode(pWorldObj);
    }

    return 0;
}

int NFCityMapGrid::IteratorWorldObject(NFICityWorldObjectFunc* pFunc, ECityWorldListType eListType)
{
    CHECK_NULL(0, pFunc);

    NFCityWorldObject* pWorldObject = nullptr;
    NFCityWorldObject* pNextWorldObject = nullptr;
    if (eListType == ECITYWLT_ALL || eListType == ECITYWLT_NPC)
    {
        pWorldObject = m_oNpcList.GetHeadNodeObj();
        while (pWorldObject)
        {
            pNextWorldObject = m_oNpcList.GetNextNodeObj(pWorldObject);

            pFunc->DoFunc(pWorldObject);

            pWorldObject = pNextWorldObject;
        }
    }

    if (eListType == ECITYWLT_ALL || eListType == ECITYWLT_PLAYER)
    {
        pWorldObject = m_oPlayerList.GetHeadNodeObj();
        while (pWorldObject)
        {
            pNextWorldObject = m_oPlayerList.GetNextNodeObj(pWorldObject);

            pFunc->DoFunc(pWorldObject);
            if (pFunc->IsBreakIterate())
            {
                break;
            }

            pWorldObject = pNextWorldObject;
        }
    }


    return 0;
}
